package com.nwu.evaluation.controller;

import com.alibaba.nacos.shaded.io.grpc.Grpc;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.nwu.common.result.Result;
import com.nwu.evaluation.domain.*;
import com.nwu.evaluation.domain.vo.*;
import com.nwu.evaluation.service.*;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.web.bind.annotation.*;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

@RestController
@Slf4j
@RequiredArgsConstructor
@Api(tags = "测评接口")
@RequestMapping("/eval")
public class EvaluationController {
    private final Evaluation1Service evaluation1Service;
    private final Evaluation2Service evaluation2Service;
    private final QuestionsService questionsService;
    private final OptionsService optionsService;
    private final ScoringStandardService scoringStandardService;
    private final EvaluationRecordsService evaluationRecordsService;
    private final OptionsDetailService optionsDetailService;

    /**
     * 用于获取所有的评估方向
     * @return
     */
    @ApiOperation("查询 评估方向")
    @GetMapping("/eval1")
    public Result listEval1(){
        return Result.success(evaluation1Service.list(null));
    }

    /**
     * 根据评估方向获取具体的评估量表列表
     * @param eval1Id
     * @return
     */

    @ApiOperation("查询 详细评估表 根据方向表id")
    @GetMapping("/{eval1Id}")
    public Result listEval2ByEval1Id(@PathVariable Long eval1Id){
        LambdaQueryWrapper<Evaluation2> evaluation2LambdaQueryWrapper =
                new LambdaQueryWrapper<Evaluation2>()
                        .select()
                        .eq(eval1Id!=null,Evaluation2::getEvaluation1Id,eval1Id);
        List<Evaluation2> evaluation2List = evaluation2Service.list(evaluation2LambdaQueryWrapper);
        List<Evaluation2Vo> evaluation2VoList = new ArrayList<>();
        for (Evaluation2 e:evaluation2List
             ) {
            Evaluation2Vo evaluation2Vo = Evaluation2Vo.builder()
                    .tableName(e.getTableName())
                    .id(e.getId())
                    .questionIntroduction(e.getQuestionIntroduction())
                    .tableIntroduction(e.getTableIntroduction())
                    .build();
            evaluation2VoList.add(evaluation2Vo);
        }
        return Result.success(evaluation2VoList);
    }

    /**
     * 根据评估量表的id获取所有的问题和选项以及选项的对应得分
     * @param eval2Id
     * @return
     */
    @ApiOperation("查询 所有问题 根据评估表id")
    @GetMapping("/eval2/{eval2Id}")
    public Result listQuestionsByEval2Id(@PathVariable Long eval2Id){
        //1，根据量表id获取所有的问题
        LambdaQueryWrapper<Questions> questionsLambdaQueryWrapper = 
                new LambdaQueryWrapper<Questions>()
                        .select()
                        .eq(eval2Id!=null,Questions::getEvaluation2Id,eval2Id);
        List<Questions> questionsList = questionsService.list(questionsLambdaQueryWrapper);
        List<QuestionsVo> questionsVoList = new ArrayList<>();
        for (Questions q:questionsList
             ) {
            QuestionsVo questionsVo = QuestionsVo.builder()
                    .question(q.getQuestion())
                    .id(q.getId())
                    .build();
            questionsVoList.add(questionsVo);
        }
        List<AllQuestions> allQuestionsList = new ArrayList<>();
        //2，对于每个问题处理
        for (QuestionsVo q:questionsVoList
             ) {
            //获取每个问题的所有选项的键值对
            Long questionId = q.getId();
            LambdaQueryWrapper<Options> optionsLambdaQueryWrapper =
                    new LambdaQueryWrapper<Options>()
                            .select()
                            .eq(questionId!=null,Options::getQuestionsId,questionId);
            List<Options> optionsList = optionsService.list(optionsLambdaQueryWrapper);
            List<FullOptions> fullOptionsList = new ArrayList<>();
            for (Options o:optionsList
                 ) {
                Long optionsDetailId = o.getOptionsDetailId();
                LambdaQueryWrapper<OptionsDetail>optionsDetailLambdaQueryWrapper =new LambdaQueryWrapper<OptionsDetail>()
                        .select()
                        .eq(optionsDetailId!=null,OptionsDetail::getId,optionsDetailId);
                FullOptions fullOptions = FullOptions.builder()
                        .id(o.getId())
                        .content(optionsDetailService.getOne(optionsDetailLambdaQueryWrapper).getContent())
                        .build();
                fullOptionsList.add(fullOptions);

            }
            AllQuestions allQuestions = AllQuestions.builder()
                    .questionsVo(q)
                    .fullOptionsList(fullOptionsList)
                    .build();
            allQuestionsList.add(allQuestions);

        }
        return Result.success(allQuestionsList);
    }

    /**
     * 根据量表id和得分筛选结果，并且结合用户id存储结果
     * @param optionsIdList
     * @param eval2Id
     * @return
     */
    @ApiOperation("查询 评估结果 并且保存记录")
    @PostMapping("/result/{eval2Id}")
    public Result getResultByEval2IdAndScore(@RequestParam List<Long> optionsIdList,@PathVariable Long eval2Id){
        //1，得分累计
        Integer sumScores = 0;
        LambdaQueryWrapper<Options> optionsLambdaQueryWrapper = new LambdaQueryWrapper<Options>()
                .select()
                        .in(Options::getId,optionsIdList);
        List<Options> optionsList = optionsService.list(optionsLambdaQueryWrapper);
        for (Options op:optionsList
             ) {
            OptionsDetail optionsDetail = optionsDetailService.getById(op.getOptionsDetailId());
            Integer score = optionsDetail.getVal();
            sumScores+=score;
        }
        log.info("sumScores={}",sumScores);
        //2，筛选结果
        LambdaQueryWrapper<ScoringStandard> scoringStandardLambdaQueryWrapper =
                new LambdaQueryWrapper<ScoringStandard>()
                        .select()
                        .ge(sumScores>=0,ScoringStandard::getMax,sumScores)
                        .lt(sumScores>=0,ScoringStandard::getMin,sumScores)
                        .eq(eval2Id!=null,ScoringStandard::getEvaluation2Id,eval2Id);
        ScoringStandard scoringStandard = scoringStandardService.getOne(scoringStandardLambdaQueryWrapper);
        //3，构建返回值，即得分累计和结果
        EvaluationResult evaluationResult = EvaluationResult.builder()
                .score(sumScores)
                .scoringStandard(scoringStandard)
                .build();
        //4.获取用户id
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        Long userId = (Long) authentication.getPrincipal();
        //5.存储得分结果和得分，并且记录用户id
        EvaluationRecords evaluationRecords = EvaluationRecords.builder()
                .score(sumScores)
                .socreId(scoringStandard.getId())
                .time(new Date())
                .userId(userId)
                .build();
        evaluationRecordsService.save(evaluationRecords);
        return Result.success(evaluationResult);
    }

    @ApiOperation("调用 用于词频")
    @GetMapping("/words")
    public List<String> getWords(@RequestParam("beginTime")String time){
        //获取当前用户id
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        Long id = (Long) authentication.getPrincipal();
        //获取测评结果list
        LambdaQueryWrapper<EvaluationRecords>evaluationRecordsLambdaQueryWrapper = new LambdaQueryWrapper<EvaluationRecords>()
                .select()
                .eq(id!=null,EvaluationRecords::getUserId,id)
                .ge(time!=null,EvaluationRecords::getTime,time)
                .lt(EvaluationRecords::getTime,new Date());
        List<EvaluationRecords> evaluationRecordsList = evaluationRecordsService.list(evaluationRecordsLambdaQueryWrapper);
        //转换为需要的数据
        List<String> words = new ArrayList<>();
        for (EvaluationRecords e:evaluationRecordsList
             ) {
            //查询对应的词语
            LambdaQueryWrapper<ScoringStandard>scoringStandardLambdaQueryWrapper = new LambdaQueryWrapper<ScoringStandard>()
                    .select()
                    .eq(e.getSocreId()!=null,ScoringStandard::getId,e.getSocreId());
            ScoringStandard scoringStandard = scoringStandardService.getOne(scoringStandardLambdaQueryWrapper);
            words.add(scoringStandard.getResult());
        }
        return words;
    }

}
